const apps = getApp()
//md5.md5('55555')

var serviceUUID = "51703e67-f03e-4e29-908e-6b05b645e2f7".toUpperCase() //主 service 的 uuid 要大写 否则iOS有问题
var writeUUID = "39c3f6d5-a117-4db1-8c43-80786eea9db5".toUpperCase(); //写读 UUID
var notifyUUID = "39c3f6d2-a117-4db1-8c43-80786eea9db0".toUpperCase(); //notify UUID

var isConnected = false //是否已经连接
var discoveryStarted = false;//是否正在搜索设备
var isInitBleDev = false;//是否已经初始设备

var macAddress = "C4:4F:33:24:76:1B"; //保存得到mac地址
var devId = '12345678'; // 系统中吸氧气机设备的ID
var bleName='';
var deviceId = 'C4:4F:33:24:76:1B';//用于连接蓝牙设备的 andion 是mac地址  ios 是加密串

let procRevData = function (revData) { } //处理接收到的数据
let gBalanceTime

function freeBleDev(obj) {
  if (!isInitBleDev) {
    return
  }
  //先关闭连接
  if (isConnected) {
    decConnected()
  }
  //再清理资源
  wx.closeBluetoothAdapter({
    success: function (res) {
      console.log(" 清理手机蓝牙资源成功");
    },
    fail(res) {
      console.error("清理蓝牙资源失败:  " + res);
    }
  })
  isInitBleDev = false
}

//断开连接,释放资源
function decConnected(obj) {
  //如果扫描操作执行了的  需要释放手机蓝牙的资源
  if (discoveryStarted) {
    stopBluetoothDevicesDiscovery()
  }
  //如果连接上了  需要断开连接操作
  if (isConnected) {
    wx.closeBLEConnection({
      deviceId: deviceId,
      success(res) {
        console.log("断开连接操作成功");
        isConnected = false;
      },
      fail(res) {
        console.error("断开连接操作失败", res);
      }
    });

    /*wx.closeBluetoothAdapter({
      success: function (res) {
        console.log(" 清理手机蓝牙资源成功");
       },
      fail(res) {
        console.log("清理手机端  蓝牙  资源失败回调  " + res);
      }
    })*/
  }
}

//判断系统版本、微信版本、定位服务等权限和信息,
function bleInit(bleMac, bleDevId, getBalanceTime,bName) {
  macAddress = bleMac
  devId = bleDevId
  deviceId = bleMac
  bleName=bName
  gBalanceTime = getBalanceTime
  //Android 从微信 6.5.7 开始支持，iOS 从微信 6.5.6 开始支持
  //第一项，如果手机是android系统，需要判断版本信息
  if (apps.getPlatform() == "android" && apps.versionCompare("6.5.7", apps.getVersion())) {
    wx.showModal({
      title: '提示',
      content: '当前微信版本过低，请更新至最新版本',
      showCancel: false
    });
    console.error("当前微信版本过低，请更新至最新版本" );
     return;
  }
  //第二项，如果手机是ios系统，需要判断版本信息
  if (apps.getPlatform() == "ios" && apps.versionCompare("6.5.6", apps.getVersion())) {
    wx.showModal({
      title: '提示',
      content: '当前微信版本过低，请更新至最新版本',
      showCancel: false
    });
    console.error("当前微信版本过低，请更新至最新版本" );
    return;
  }
  //版本  以及  平台校验完毕后   需要判断蓝牙的相关信息
  //微信小程序 android6.0手机需要开启位置服务，否则扫描不到设备
  console.log("当前系统版本：" + apps.getSystem());//Android 8.1.0
  console.log("当前微信版本：" + apps.getVersion());
  if (apps.getPlatform() == "android") {
    console.log("android手机  当前系统版本号：" + apps.getSystem().replace("Android", "").replace(" ", ""));
    //android版本高于6.0.0
    if (!apps.versionCompare("6.0.0", apps.getSystem().replace("Android", "").replace(" ", ""))) {
      console.log("当前系统版本高于6.0.0");

    } else if (!apps.versionCompare(apps.getSystem().replace("Android", "").replace(" ", "")), "4.3.0") {
      //系统版本低于4.3的,使用不了ble蓝牙
      wx.showModal({
        title: '温馨提示',
        content: '您的手机系统版本较低，无法操作BLE蓝牙设备',
        showCancel: false,
      });
      //执行quit机制
      console.error("您的手机系统版本较低，无法操作BLE蓝牙设备" );
    } else {
      console.log("系统版本低于6.0.0但高于4.3.0");
      //除去android系统的手机(由于最开始过滤了能支持蓝牙的最低微信版本   所以此处无需再判断)
      bleDevInit();
    }
  }
  //除android以外的ios或者其他系统
  bleDevInit();
}
/**
 * 开启当前手机ble蓝牙适配器，注册相关的监听事件
 * @param {} obj 
 */
function bleDevInit() {
  //1、判断手机蓝牙是否开启
  wx.openBluetoothAdapter({
    success: function (res) {
      isInitBleDev = true
      console.log("初始化蓝牙适配器成功");
      //开启蓝牙适配器的状态变化监听
      wx.onBluetoothAdapterStateChange(function (res) {
        console.log("蓝牙适配器状态变化", res);
      });

      if (apps.getPlatform() == "ios") {//如果是iOS系统,因为无法用MAC地址直连,则调用开启扫描周围设备获取蓝牙设备ID 
        startBluetoothDevicesDiscovery()//启动扫描周围设备获取蓝牙设备ID 
      } else if (apps.getPlatform() == "android") {//如果是android系统,则用MAC地址直连
        //startBluetoothDevicesDiscovery()
        //连接设备
        if (gBalanceTime)
          gBalanceTime()
      }
    },
    fail: function (res) {
      console.error("初始化蓝牙适配器失败")
      wx.showModal({
        title: '请打开蓝牙',
        content: '请检查手机蓝牙是否打开,需要蓝牙获取吸氧机信息,否则无法使用',
        showCancel: false,
      });
      //执行quit机制
      //decConnected(obj);
    }
  })
}

/**
 * 扫描蓝牙设备
 */
function startBluetoothDevicesDiscovery() {
  if (discoveryStarted) {
    return;
  }
  onBluetoothDeviceFound()//监听寻找新设备事件
  discoveryStarted = true
  wx.startBluetoothDevicesDiscovery({
    //services: [serviceUUID],
    allowDuplicatesKey: false,
    success: (res) => {
      console.log('启动搜索蓝牙设备 成功')
    },
    fail(res) {
      //asddErrorCallback(res.errCode, "");
      console.error('启动搜索蓝牙设备 失败', res);
    }
  })
}

/**
 * 监听寻找新设备事件
 * 注意咯： 这里有展示三种不同方式来连接设备，请看备注【mac, name, 根据系统的】 各取所需吧。
 */
function onBluetoothDeviceFound() {
  wx.onBluetoothDeviceFound((res) => {
    //console.log('广播数据结果:', res);
    res.devices.forEach(device => {
      //console.log('搜索到deviceId:', device);//.deviceId
      let bName = device.name.toUpperCase();
      if (bName == bleName) {
        deviceId = device.deviceId;
        //停止搜寻附近的蓝牙外围设备
        stopBluetoothDevicesDiscovery();
        //连接设备
        if(gBalanceTime)
          gBalanceTime()
        console.log('找到', device);
        return
      }

      // 转换后, 根据协议文档取需要数据 （advertisData不一定有数据）
      /*if (device.advertisData != null) { //判断对象是否为null，advertisData不一定有
        var hexStr = ab2hex(device.advertisData);
        console.log("广播数据中转换后：advertisData---->" + hexStr);
      }*/
      // 用rssi 信号强度来判断,连接信号最强的

    })
  })
}


//停止搜寻附近的蓝牙外围设备。
function stopBluetoothDevicesDiscovery() {
  if (discoveryStarted)
    wx.stopBluetoothDevicesDiscovery()
  discoveryStarted = false
}

//连接服务,revDate 为连接后处理接收到数据的函数
function bleConnecte(revDate) {
  procRevData = revDate
  //关闭扫描
  stopBluetoothDevicesDiscovery();

  if (isConnected) {
    console.error("设备已经连接:", deviceId)
    return
  }
  //连接状态变化监听 --监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接，设备丢失，连接异常断开等等
  //监听低功耗蓝牙连接状态的改变事件
  wx.onBLEConnectionStateChange(function (res) {
    // 该方法回调中可以用于处理连接意外断开等异常情况
    //console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
    if (res.connected == false) {
      console.warn("蓝牙设备连接断开", res.deviceId);
      isConnected = false
      //cmd.setActionType(0)//初始化流程
    } else {
      console.log("蓝牙设备连接成功:", res.deviceId);
      isConnected = true
    }
  });
  console.log("连接设备:", deviceId)
  wx.createBLEConnection({
    deviceId: deviceId,
    success: function (res) {
      //需要完整获取服务和特征,并且设置
      getBLEDeviceServices()
    },
    fail: function (res) {
      wx.showToast({
        title: '连接设备失败',
        icon: 'success',
        duration: 1000
      })
      //bluetoothStatus(res.errCode)
      console.error("连接设备失败:", res)
    }
  })

}


/**
 * 获取蓝牙所有服务
 */
function getBLEDeviceServices() {
  setRevNotify();//设置属性变化通知
  if (apps.getPlatform() == "android") {
    wx.notifyBLECharacteristicValueChange({//设置notify监听
      deviceId: deviceId,
      serviceId: serviceUUID,
      characteristicId: notifyUUID,
      state: true,
      success(res) {
        console.log('android notification通知数据成功');
      },
      fail(res) {
        console.error('android notification通知数据失败', res);
      }
    })   
    return
  }
  console.log('getBLEDeviceServices ', deviceId);
  wx.getBLEDeviceServices({
    deviceId: deviceId,
    success: (res) => {
      // console.log("获取蓝牙设备所有服务(service)", res);
      for (let i = 0; i < res.services.length; i++) {
        let tmpUuid = res.services[i].uuid.toUpperCase();
        if ((res.services[i].isPrimary) && (tmpUuid.indexOf(serviceUUID) != -1)) {
          console.log('找到蓝牙服务: ', tmpUuid);
          getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
        }
      }
    },
    fail: (res) => {
      console.log('getBLEDeviceServices fail', res);
      //asddErrorCallback(res.errCode, "");
    }
  })
}

/**
* 获取指定服务所有蓝牙特征值
*/
function getBLEDeviceCharacteristics(deviceId, serviceId) {
  wx.getBLEDeviceCharacteristics({
    deviceId: deviceId,
    serviceId: serviceId,
    success: (res) => {
      // console.log('蓝牙设备特征值信息:', res);
      for (let i = 0; i < res.characteristics.length; i++) {
        let item = res.characteristics[i]
        var itemUUID = item.uuid.toUpperCase(); //转大写
        if (item.properties.read && itemUUID == writeUUID) {
          console.log('找到服务read特征 ', itemUUID);
          /*wx.readBLECharacteristicValue({//试读一次
            deviceId: deviceId,
            serviceId: serviceId,
            characteristicId: item.uuid,
          })*/
        }
        if (item.properties.write && itemUUID == writeUUID) {
          console.log('找到服务write特征 ', itemUUID);
          deviceId = deviceId
          //发送指令【说明：如需连接设备后发相关指令可以在这里调用】需要延时1秒
        }

        if (notifyUUID == itemUUID) {
          if (item.properties.notify || item.properties.indicate) {
            console.log('找到服务notify indicate特征 ', itemUUID);
            //console.log('调用notifyBLECharacteristicValueChange前', item.uuid);
            wx.notifyBLECharacteristicValueChange({//设置notify监听
              deviceId: deviceId,
              serviceId: serviceId,
              characteristicId: item.uuid,
              state: true,
              success(res) {
                console.log('notification通知数据成功');
              },
              fail(res) {
                console.log('notifyBLECharacteristicValueChange 失败', res);
              }
            })
          }
        }
      }
    },
    fail: (res) => {
      console.error('getBLEDeviceCharacteristics fail', res)
      //asddErrorCallback(res.errCode, "");
    }
  })
  
}

// 操作之前先监听，保证第一时间获取数据
//读取特征值数据监听事件  ---- wx.readBLECharacteristicValue(Object object)调用后，若要取得其中的数据，需要再此回调中获取
//notify 调用notifyBLECharacteristicValueChange 后的数据也从这里获取
function setRevNotify(){
  wx.onBLECharacteristicValueChange(function (res) {
    //console.log(`特征 ${res.characteristicId} 值改变 ${res.value}`)
    //console.log("操作类型:" + action_type);
    //var resData = cmd.ab2hex(res.value);
    //console.log("设备返回数据--->", resData); //5d0000000001be304d
    // 判断不同类型处理数据 处理蓝牙命令
    procRevData(res.value)
    /*let retValue = cmd.exeCmd(res.value, writeValue)
    console.log("retValue=", retValue);
    if (retValue == 1) {
      decConnected();
    }*/
  })
}

/**
 * 写特征属性数据
 * @param {} sendValue 发送的数据
 * @param revData 接收的数据的处理函数
 */
function writeValue(sendValue, revData) {
  procRevData = revData
  //console.log("发送数据", cmd.ab2hex(sendValue)); //5d0000000001be304d
  wx.writeBLECharacteristicValue({
    deviceId: deviceId,
    serviceId: serviceUUID,
    characteristicId: writeUUID,
    value: sendValue,
    success: function (res) {
      console.log("发送命令成功：");
      procRevData();//处理发送完成后的下一步
      return true
    },
    fail(res) {
      console.error("发送命令失败", res);
      return fase
      //quit(res);
    }
  })
}

/**
 * 延时1秒写入数据
 * @param {} sendValue 发送的数据
 * @param revData 接收的数据的处理函数
 */
function writeTimeData(sendValue, revData) {
  setTimeout(writeValue(sendValue, revData), 1000)
}

/**
 * 蓝牙连接过程中错误码
 * 10000 / 10006
 */
function bluetoothStatus(errorType) {
  switch (errorType) {
    case 10001:
      wx.showModal({
        title: '提示',
        content: '请检查手机蓝牙是否打开',
        showCancel: false
      })
      break;
    case 10002:
      wx.showToast({
        title: '没有找到指定设备',
        icon: 'none'
      })
      break;
    case 10003:
      wx.showToast({
        title: '连接失败',
        icon: 'none'
      })
      closeBLEConnection();
      break;
    case 10004:
      wx.showToast({
        title: '没有找到指定服务',
        icon: 'none'
      })
      closeBLEConnection();
      break;
    case 10005:
      wx.showToast({
        title: '没有找到指定特征值',
        icon: 'none'
      })
      closeBLEConnection();
      break;
    case 10007:
    case 10008:
    case 10013:
      wx.showToast({
        title: '设备启动失败，请重试',
        icon: 'none'
      })
      break;
    case 10009:
      wx.showModal({
        title: '提示',
        content: '当前系统版本过低，请更新版本体验',
        showCancel: false
      })
      break;
    case 10012:
      wx.showToast({
        title: '连接超时',
        icon: 'none'
      })
      break;
  }
}

//export const bleDevInit = bleDevInit;
//export const bleInit //= bleInit;
//export const ab2hex = ab2hex;
//转化成小程序模板语言 这一步非常重要 不然无法正确调用
module.exports = {
  bleInit: bleInit,//蓝牙初始化
  freeBleDev: freeBleDev,//释放蓝牙资源
  bleConnecte: bleConnecte,//打开连接
  decConnected: decConnected, //关闭连接
  writeValue: writeValue, //发送数据
  writeTimeData: writeTimeData//延时1秒发送数据
  //ab2hex: ab2hex
};